function Observer(data) {
    this.data = data;
    this.walk(data);
}

Observer.prototype = {
    walk: function(data) {
        var me = this;
        Object.keys(data).forEach(function(key) {
            me.convert(key, data[key]);
        });
    },
    convert: function(key, val) {
        this.defineReactive(this.data, key, val);
    },
    defineReactive: function(data, key, val) {
        //每一个data中的属性都会分配到一个dep闭包!!!
        var dep = new Dep();

        var childObj = observe(val);

        //data中的每一个属性都会执行到下述代码
        //真正实现数据劫持的代码
        Object.defineProperty(data, key, {
            enumerable: true, // 可枚举
            configurable: false, // 不能再define
            get: function() {
                //为obj调  为msg调 为text调
                //不管为谁调 Dep.target都是v-html对应的watcher!
                if (Dep.target) {
                    dep.depend();
                }
                return val;
            },
            set: function(newVal) {
                //newVal : hello Kitty
                //val : "hello world"
                if (newVal === val) {
                    return;
                }
                val = newVal;
                childObj = observe(newVal);

                dep.notify();
            }
        });
    }
};

//实现数据劫持的函数
function observe(value, vm) {
    //当value不是一个对象时;observe的递归才会结束
    if (!value || typeof value !== 'object') {
        return;
    }
    return new Observer(value);
};




var uid = 0;

function Dep() {
    this.id = uid++;
    this.subs = [];
}

Dep.prototype = {
    //sub:watcher
    addSub: function(sub) {
        this.subs.push(sub);
    },

    depend: function() {
        // Dep.target:v-html对应的watcher
        // this:对应的dep!
        Dep.target.addDep(this);
    },

    notify: function() {
        this.subs.forEach(function(sub) {
            sub.update();
        });
    }
};

Dep.target = null;